package com.example.matchingengine.service.strategy;

import com.example.matchingengine.model.Order;
import com.example.matchingengine.model.Order.OrderStatus;
import com.example.matchingengine.service.event.TradeEvent;
import com.example.matchingengine.service.model.OrderBook;

import static com.example.matchingengine.model.Order.OrderStatus.*;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedList;

/**
 * 限价卖单匹配策略
 */
@Slf4j
public class LimitSellStrategy extends AbstractMatchingTemplate {
    
    @Override
    protected void doMatch(Order order, OrderBook orderBook) {
        log.info("执行限价卖单匹配: {}, 价格: {}, 数量: {}", 
                order.getId(), order.getPrice(), order.getQuantity());
        
        // 调用本地的限价卖单匹配逻辑
        matchLimitSellOrder(order, orderBook);
    }
    
    @Override
    public String getStrategyType() {
        return "LIMIT_SELL";
    }
    
    /**
     * 撮合限价卖单
     */
    private void matchLimitSellOrder(Order sellOrder, OrderBook orderBook) {
        // FOK订单检查：如果不能完全成交，直接取消
        if (sellOrder.getTimeInForce() == Order.TimeInForce.FOK) {
            if (!orderBook.canFillCompletely(sellOrder)) {
                sellOrder.setStatus(OrderStatus.CANCELED);
                sellOrder.setUpdateTime(LocalDateTime.now());
                orderBook.sendOrderStatusUpdate(sellOrder);
                return;
            }
        }

        // 执行撮合逻辑
        matchSellOrderCore(sellOrder, orderBook);

        // 处理未成交部分（针对IOC和FOK订单）
        orderBook.handleUnfilledPortion(sellOrder);
    }
    
    /**
     * 撮合卖单核心逻辑
     */
    private void matchSellOrderCore(Order sellOrder, OrderBook orderBook) {
        boolean fullyMatched = false;
        boolean hasMatched = false; // 标记是否有成交

        // 循环匹配买盘订单
        while (!orderBook.getBuyOrders().isEmpty() && !fullyMatched) {
            // 获取买盘最高价格
            BigDecimal highestBuyPrice = orderBook.getBuyOrders().firstKey();

            // 如果卖单价格大于买单最高价格，无法撮合，退出循环
            if (sellOrder.getPrice().compareTo(highestBuyPrice) > 0) {
                break;
            }

            // 获取该价格下的订单列表
            LinkedList<Order> ordersAtPrice = orderBook.getBuyOrders().get(highestBuyPrice);
            if (ordersAtPrice.isEmpty()) {
                orderBook.getBuyOrders().remove(highestBuyPrice);
                continue;
            }

            // 获取该价格下最早的订单（时间优先）
            Order buyOrder = ordersAtPrice.getFirst();

            // 计算可成交数量
            BigDecimal remainingSellQty = sellOrder.getQuantity().subtract(sellOrder.getFilledQuantity());
            BigDecimal remainingBuyQty = buyOrder.getQuantity().subtract(buyOrder.getFilledQuantity());
            BigDecimal matchQty = remainingSellQty.min(remainingBuyQty);

            // 更新订单成交数量
            sellOrder.setFilledQuantity(sellOrder.getFilledQuantity().add(matchQty));
            buyOrder.setFilledQuantity(buyOrder.getFilledQuantity().add(matchQty));
            hasMatched = true; // 标记有成交

            // 生成成交事件
            TradeEvent tradeEvent = new TradeEvent(
                    buyOrder.getId(),
                    sellOrder.getId(),
                    orderBook.getSymbol(),
                    buyOrder.getPrice(), // 成交价格以买单价格为准
                    matchQty,
                    LocalDateTime.now()
            );

            // 发送成交消息到RocketMQ
            orderBook.sendTradeEvent(tradeEvent);

            // 记录成交计数
            orderBook.incrementTradeCounter();

            // 检查买单是否完全成交
            if (buyOrder.getFilledQuantity().compareTo(buyOrder.getQuantity()) >= 0) {
                // 从买盘移除已完全成交的订单
                Order removedOrder = ordersAtPrice.removeFirst();
                // 从订单映射表中移除
                orderBook.getOrderMap().remove(removedOrder.getId());
                if (ordersAtPrice.isEmpty()) {
                    orderBook.getBuyOrders().remove(highestBuyPrice);
                }
                buyOrder.setStatus(OrderStatus.FILLED);
                buyOrder.setUpdateTime(LocalDateTime.now());

                // 发送订单状态更新消息
                orderBook.sendOrderStatusUpdate(buyOrder);
            } else {
                // 部分成交
                buyOrder.setStatus(OrderStatus.PARTIALLY_FILLED);
                buyOrder.setUpdateTime(LocalDateTime.now());

                // 发送订单状态更新消息
                orderBook.sendOrderStatusUpdate(buyOrder);
            }

            // 检查卖单是否完全成交
            if (sellOrder.getFilledQuantity().compareTo(sellOrder.getQuantity()) >= 0) {
                sellOrder.setStatus(OrderStatus.FILLED);
                fullyMatched = true;
            } else {
                sellOrder.setStatus(OrderStatus.PARTIALLY_FILLED);
            }

            sellOrder.setUpdateTime(LocalDateTime.now());
        }

        // 只有在有成交的情况下才发送订单状态更新消息
        if (hasMatched) {
            orderBook.sendOrderStatusUpdate(sellOrder);
        }
    }
}